<template>
  <div class="wrap">
    <div class="title">
      <div>
        <van-icon
          name="arrow-left"
          size="20"
          style="margin-left: 10px"
          @click="onClickLeft"
        />
      </div>
      <div>{{ roomInfo.roomName + `(${store.personList.length})` }}</div>
      <div>
        <van-icon
          name="ellipsis"
          size="22"
          style="margin-right: 10px"
          @click="onClickRight"
        />
      </div>
    </div>
    <div class="content_box" id="box" ref="scrollBox">
      <div class="timer">2022-08-02 11:08:07</div>
      <div v-for="(item, index) in store.messageList" :key="index">
        <template v-if="item.msgType == MsgTypeEnum.TIP">
          <div class="timer">{{ item.msg }}</div>
        </template>
        <template v-else>
          <div :class="item.position == 'left' ? 'userbox2' : 'userbox'">
            <div :class="item.position == 'left' ? 'nameInfo2' : 'nameInfo'">
              <div style="font-size: 14px">{{ item.user?.userName }}</div>
              <div
                :class="
                  item.position == 'left' ? 'contentText2' : 'contentText'
                "
              >
                <template v-if="item.msgType == MsgTypeEnum.IMAGE">
                  <chat-image width="100%" height="100px" :src="item.msg" />
                </template>
                <template v-else-if="item.msgType == MsgTypeEnum.VIDEO">
                  <video class="send-video" controls>
                    <source :src="item.msg" />
                    您的浏览器不支持 HTML5 video 标签。
                  </video>
                </template>
                <template v-else-if="item.msgType == MsgTypeEnum.FILE">
                  <div class="file-preview">
                    <div></div>
                    <div>
                      <font-awesome-icon
                        v-show="plusFlag"
                        :icon="['fa', 'file']"
                      />
                    </div>
                  </div>
                </template>
                <div v-else v-html="item.msg"></div>
                <div
                  :class="
                    item.position == 'left'
                      ? 'loadingContent1'
                      : 'loadingContent'
                  "
                >
                  <van-loading
                    v-if="item.msgStatus === MsgStatusEnum.PENDING"
                    type="spinner"
                    color="#316bff"
                    size="16"
                  />
                  <font-awesome-icon
                    v-else-if="item.msgStatus === MsgStatusEnum.REJECTED"
                    class="redColor"
                    :icon="['fa', 'circle-exclamation']"
                  />
                </div>
              </div>
            </div>
            <div>
              <chat-image
                round
                width="50px"
                height="50px"
                :src="item.user?.avatar"
              />
            </div>
          </div>
        </template>
      </div>
      <div style="height: 200px"></div>
    </div>
    <div class="chat-bottom">
      <div class="send-msg">
        <div class="box-textarea">
          <amis-editor
            :editor="editor"
            ref="editorRef"
            class="im-container"
            placeholder="输入内容..."
            @input="handleInput"
            @focus="handleFocus"
          >
          </amis-editor>
        </div>
        <div class="send-btn">
          <font-awesome-icon
            class="emoji"
            v-show="emojiFlag"
            @click="showEmoji"
            :icon="['far', 'face-smile']"
          />
          <font-awesome-icon
            class="plus"
            v-show="plusFlag"
            :icon="['fa', 'plus']"
            @click="showOther"
          />
          <van-button
            v-show="sendFlag"
            color="#316BFF"
            class="send"
            type="primary"
            @click="sendOut"
            >发送</van-button
          >
        </div>
      </div>
      <!--发送工具栏-->
      <div
        v-if="otherShow"
        v-click-outside="handleOutsideEmo"
        class="message-other"
      >
        <div class="other-scroll-view">
          <ul>
            <li>
              <div class="btn-icon">
                <oss-upload
                  @complete="handleUploadComplete($event, MsgTypeEnum.IMAGE)"
                  @start="handleUploadStart($event, MsgTypeEnum.IMAGE)"
                >
                  <font-awesome-icon
                    v-show="plusFlag"
                    :icon="['fa', 'camera']"
                  />
                </oss-upload>
              </div>
              <span>图片</span>
            </li>
            <li>
              <div class="btn-icon">
                <oss-upload
                  @complete="handleUploadComplete($event, MsgTypeEnum.VIDEO)"
                  @start="handleUploadStart($event, MsgTypeEnum.VIDEO)"
                >
                  <font-awesome-icon
                    v-show="plusFlag"
                    :icon="['fa', 'video']"
                  />
                </oss-upload>
              </div>
              <span>视频</span>
            </li>
            <li>
              <div class="btn-icon">
                <oss-upload
                  @complete="handleUploadComplete($event, MsgTypeEnum.FILE)"
                  @start="handleUploadStart($event, MsgTypeEnum.FILE)"
                >
                  <font-awesome-icon v-show="plusFlag" :icon="['fa', 'file']" />
                </oss-upload>
              </div>
              <span>文件</span>
            </li>
            <li>
              <div class="btn-icon">
                <oss-upload
                  @complete="handleUploadComplete($event, MsgTypeEnum.FILE)"
                  @start="handleUploadStart($event, MsgTypeEnum.FILE)"
                >
                  <font-awesome-icon v-show="plusFlag" :icon="['fa', 'file']" />
                </oss-upload>
              </div>
              <span>音频</span>
            </li>
          </ul>
        </div>
      </div>
      <!--表情-->
      <div
        v-if="emojiShow"
        v-click-outside="handleOutsideEmo"
        class="message-other"
      >
        <emo @select="selectIcon"></emo>
      </div>
    </div>
    <search-person @complete="handleAtComplete" ref="atRef"></search-person>
  </div>
</template>
<script lang="ts">
import {
  defineComponent,
  reactive,
  toRefs,
  getCurrentInstance,
  watchEffect,
  nextTick,
} from "vue";
import dayjs from "dayjs";
import { ElMessage, ElMessageBox } from "element-plus";
import MySender from "@/utils/socket/MySender";
import userStore from "@/store/user";
import MsgCommand from "@/utils/socket/enums/MsgCommand";
import MsgTypeEnum from "@/utils/socket/enums/MsgTypeEnum";
import { showToast, showConfirmDialog } from "vant";
import AmisEditor from "@/components/AmisEditor/h5.vue";
import ossUpload from "@/components/ossUpload.vue";
import { v4 as uuidv4 } from "uuid";
import MsgStatusEnum from "@/utils/socket/enums/MsgStatusEnum";
import emoji from "@/assets/emoji.ts";
import { useSocket } from "@/utils/socket/useSocket";
import emo from "./emo.vue";
import searchPerson from "./searchPerson.vue";
import { ClickOutside as vClickOutside } from "element-plus";

export default defineComponent({
  props: {
    roomInfo: {
      type: Object,
      default: () => {},
    },
    userInfo: {
      type: Object,
      default: () => {},
    },
  },
  components: {
    AmisEditor,
    ossUpload,
    emo,
    searchPerson,
  },
  directives: {
    ClickOutside: vClickOutside,
  },
  setup(props: any, { emit }: any) {
    const state = reactive({
      loading: false,
      inputValue: "",
      emojiFlag: true,
      plusFlag: true,
      sendFlag: false,
      otherShow: false,
      emojiShow: false,
      fileImg: null,
      msgInfo: {},
      emojiData: emoji,
    });

    const store = userStore();
    const { proxy } = getCurrentInstance() as any;

    const { sendInfoNetWorkFun, sendLocalMsgFun } = useSocket();
    const sendOut = async () => {
      await nextTick();
      const room = store.roomInfo;
      if (state.inputValue.trim() == "") {
        showToast("发送内容不能为空");
        return false;
      }
      const msgInfo = {
        msgId: uuidv4().replaceAll("-", ""),
        userId: room.userId,
        roomId: room.roomId,
        msgType: MsgTypeEnum.TEXT,
        msgStatus: MsgStatusEnum.PENDING,
        msg: state.inputValue,
      };
      sendLocalMsgFun(msgInfo);
      setTimeout(() => {
        sendInfoNetWorkFun(msgInfo);
        proxy.$refs.editorRef.setInnerHtml("");
      }, 500);
    };

    const onClickRight = () => {
      emit("right", {});
    };

    const onClickLeft = () => {
      emit("leave", {});
    };

    const handleInput = (val: any) => {
      debugger;
      const lastChar = val.slice(-1);
      if (lastChar === "@") {
        // 开始@人员了
        proxy.$refs.atRef.open(
          store.personList.map((x) => {
            return {
              name: x.userName,
              code: x.userCode,
            };
          })
        );
      } else {
        state.inputValue = val;
      }
    };

    const handleUploadComplete = (url: any, type: any) => {
      state.msgInfo.msg = url;
      sendInfoNetWorkFun(state.msgInfo);
    };

    const handleUploadStart = (file: any, type: any) => {
      state.msgInfo = {
        msgId: uuidv4().replaceAll("-", ""),
        msgType: type,
        user: props.userInfo,
        position: "right",
        msgStatus: MsgStatusEnum.PENDING,
        msg: URL.createObjectURL(file),
      };
      sendLocalMsgFun(state.msgInfo);
    };

    watchEffect(() => {
      if (state.inputValue.trim() === "") {
        state.plusFlag = true;
        state.sendFlag = false;
      } else {
        state.plusFlag = false;
        state.sendFlag = true;
      }
    });

    const showOther = () => {
      state.otherShow = !state.otherShow;
      if (state.otherShow) {
        state.emojiShow = false;
      }
    };

    // 表情包
    const showEmoji = () => {
      state.emojiShow = !state.emojiShow;
      if (state.emojiShow) {
        state.otherShow = false;
      }
    };

    const handleFocus = () => {
      state.otherShow = false;
      state.emojiShow = false;
    };

    const selectIcon = async (icon: any) => {
      await nextTick();
      let img = `<img src="${icon.icon}" alt="${icon.title}" class='emo-image' width="70px"  height="70px" />`;
      const room = store.roomInfo;
      const msgInfo = {
        msgId: uuidv4().replaceAll("-", ""),
        userId: room.userId,
        roomId: room.roomId,
        msgType: MsgTypeEnum.TEXT,
        msgStatus: MsgStatusEnum.PENDING,
        msg: img,
      };
      sendLocalMsgFun(msgInfo);
      setTimeout(() => {
        sendInfoNetWorkFun(msgInfo);
        
      }, 500);
    };

    const handleOutsideEmo = () => {
      handleFocus();
    };

    const handleAtComplete = (val) => {
      proxy.$refs.editorRef.insertAt(val.result);
    };

    return {
      ...toRefs(state),
      sendOut,
      store,
      onClickRight,
      onClickLeft,
      MsgTypeEnum,
      handleFocus,
      handleInput,
      showOther,
      showEmoji,
      handleUploadComplete,
      handleUploadStart,
      MsgStatusEnum,
      selectIcon,
      handleOutsideEmo,
      vClickOutside,
      handleAtComplete,
    };
  },
});
</script>
<style lang="less" scoped>
.wrap {
  height: 100vh;
  width: 100%;
  display: flex;
  flex-direction: column;
  background: #ffffff;

  .title {
    height: 60px;
    width: 100%;
    font-size: 18px;
    background-color: #316bff;
    color: #ffffff;
    display: flex;
    justify-content: space-between;
    align-items: center;
  }

  /* 底部聊天发送栏 */
  .chat-bottom {
    width: 100%;
    background: #f5f4f5;
    min-height: 60px;
    max-height: 600px;
    position: fixed;
    bottom: 0;
    .send-msg-only {
      bottom: 0;
    }

    .send-msg-other {
      bottom: 100px;
    }

    .send-msg {
      display: flex;
      padding: 8px 15px;
      width: 100%;
      flex-direction: row;
      align-content: flex-end;
      justify-content: flex-end;
      height: 100%;
      background: #f5f4f5;
    }

    .box-textarea {
      flex: 1;
      .im-container {
        width: auto;
        height: auto;
        min-height: 30px;
        max-height: 200px;
        background: #fff;
        border-radius: 4px;
        font-size: 16px;
        font-family: PingFang SC;
        color: #666666;
        line-height: 22px;
        padding: 2px 4px;
      }
    }

    .send-btn {
      display: flex;
      flex-direction: row;
      align-content: center;
      align-items: center;
      justify-content: center;
      color: #999999;

      .send {
        margin-left: 5px;
        font-size: 14px;
        font-family: PingFang SC;
        font-weight: 500;
        line-height: 14px;
        margin-left: 5px;
      }
      .emoji,
      .plus {
        font-family: PingFang SC;
        font-weight: 500;
        line-height: 14px;
        font-size: 25px;
        margin-left: 5px;
      }
    }
  }

  .message-other {
    width: 100%;
    background: #f4f5f7;
    display: flex;
    width: 100%;
    height: 150px;
    overflow: auto;
    bottom: 0;

    .other-scroll-view {
      ul {
        display: flex;
        flex-wrap: wrap;
        padding: 8px 15px;
        li {
          margin: 8px;
          display: flex;
          align-items: center;
          flex-direction: column;
          justify-content: center;
          flex-wrap: wrap;
          cursor: pointer;
          transition: all 0.2s ease 0s;
          color: #000;
          border-radius: 10px;

          .btn-icon {
            display: block;
            min-width: 40px;
            min-height: 40px;
            border-radius: 10px;
            font-size: 18px;
            display: flex;
            justify-content: center;
            align-items: center;
            background: #ffffff;
          }

          span {
            flex: 1;
            font-size: 14px;
            line-height: 30px;
          }
        }

        .btn-icon:hover {
          box-shadow: rgba(50, 50, 93, 0.25) 0px 30px 60px -12px inset,
            rgba(0, 0, 0, 0.3) 0px 18px 36px -18px inset;
        }
      }
    }
  }

  .content_box {
    padding: 10px 10px;
    flex: 1;
    overflow: auto;
  }
}

.send-video {
  margin: 0 10px;
}

.timer {
  text-align: center;
  color: #999999;
  font-size: 13px;
  line-height: 26px;
}

/* 发送的信息样式 */
/* 
  右边消息思路解释：首先大盒子userbox内放两个盒子，一个放头像，一个放用户名和发送的内容，我们先用flex让他横向排列。
  然后把写文字的大盒子设置flex：1。这个属性的意思就是让这个元素撑满父盒子剩余位置。然后我们再把文字盒子设置flex，并把他对齐方式设置为尾部对齐就完成了基本的结构，然后微调一下就可以了
  */
.userbox {
  width: 100%;
  display: flex;
  margin-bottom: 10px;
}
.nameInfo {
  /* 用flex：1把盒子撑开 */
  flex: 1;
  margin-right: 10px;
  /* 用align-items把元素靠右对齐 */
  display: flex;
  flex-direction: column;
  align-items: flex-end;
}
.contentText {
  background-color: #f5f4f5;
  position: relative;
  /* 把内容部分改为行内块元素，因为盒子flex：1把盒子撑大了，所以用行内块元素让内容宽度不根据父盒子来 */
  display: inline-block;
  /* 这四句是圆角 */
  // border-top-left-radius: 10px;
  // border-top-right-radius: 0px;
  // border-bottom-right-radius: 10px;
  // border-bottom-left-radius: 10px;
  border-radius: 5px;
  /* 最大宽度限定内容输入到百分61换行 */
  max-width: 61%;
  padding: 5px 10px;
  /* 忽略多余的空白，只保留一个空白 */
  white-space: normal;
  /* 换行显示全部字符 */
  word-break: break-all;
  margin-top: 3px;
  font-size: 14px;
}

/* 接收的信息样式 */
/* 
  左边消息思路解释：跟上面一样，就是换一下位置，首先通过把最外层大盒子的排列方式通过flex-direction: row-reverse;属性翻转，也就是头像和文字盒子换位置
  然后删除掉尾部对齐方式，因为不写这个默认是左对齐的。我们写的左边就没必要再写了。
  */
.userbox2 {
  width: 100%;
  display: flex;
  flex-direction: row-reverse;
  margin-bottom: 10px;
}
.nameInfo2 {
  /* 用flex：1把盒子撑开 */
  flex: 1;
  margin-left: 10px;
}
.contentText2 {
  background-color: #316bff;
  position: relative;
  color: #ffffff;
  /* 把内容部分改为行内块元素，因为盒子flex：1把盒子撑大了，所以用行内块元素让内容宽度不根据父盒子来 */
  display: inline-block;
  border-radius: 5px;
  /* 这四句是圆角 */
  // border-top-left-radius: 0px;
  // border-top-right-radius: 10px;
  // border-bottom-right-radius: 10px;
  // border-bottom-left-radius: 10px;
  /* 最大宽度限定内容输入到百分61换行 */
  max-width: 61%;
  padding: 5px 10px;
  /* 忽略多余的空白，只保留一个空白 */
  white-space: normal;
  /* 换行显示全部字符 */
  word-break: break-all;
  margin-top: 3px;
  font-size: 14px;
}

.loadingContent {
  position: absolute;
  left: -20px;
  top: calc(50%);
  transform: translateY(-50%);
}

.loadingContent1 {
  position: absolute;
  right: -20px;
  top: calc(50%);
  transform: translateY(-50%);
}

</style>
  